package mark.tom.friend.view.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;

import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.google.zxing.client.android.Intents;
import com.liaoinstan.springview.container.AcFunFooter;
import com.liaoinstan.springview.container.AcFunHeader;
import com.liaoinstan.springview.widget.SpringView;
import com.squareup.phrase.Phrase;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import mark.tom.friend.app.CustomApplication;
import mark.tom.friend.base.activity.BaseActivity;
import mark.tom.friend.base.util.RxViewUtil;
import mark.tom.friend.base.util.SnackBarUtil;
import mark.tom.friend.base.util.SystemUtil;
import mark.tom.friend.bean.bo.ConfigRecordBO;
import mark.tom.friend.bean.vo.ConfigRecordVO;
import mark.tom.friend.component.DaggerAppConfigComponent;
import mark.tom.friend.consts.ActivityRouterConsts;
import mark.tom.friend.consts.BundleKeyConsts;
import mark.tom.friend.contract.AppConfigContract;
import mark.tom.friend.module.AppConfigModule;
import mark.tom.friend.presenter.AppConfigPresenter;
import mark.tom.friend.roll.R;
import mark.tom.friend.view.adapter.RecordListAdapter;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.OnNeverAskAgain;
import permissions.dispatcher.OnPermissionDenied;
import permissions.dispatcher.OnShowRationale;
import permissions.dispatcher.PermissionRequest;
import permissions.dispatcher.RuntimePermissions;
import timber.log.Timber;

import static mark.tom.friend.consts.BundleKeyConsts.APP_CONFIG_GROUP_EXTRA;
import static mark.tom.friend.consts.BundleKeyConsts.APP_CONFIG_GROUP_SERVER;
import static mark.tom.friend.consts.BundleKeyConsts.BUNDLE_KEY_APP_CONFIG_CONTENT;

@RuntimePermissions
@Route(path = ActivityRouterConsts.ROUTER_APP_CONFIG)
public class AppConfigActivity extends BaseActivity implements AppConfigContract.View {

    private final static String APP_NAME_TEMPLATE = "app_name";
    private final static String APP_GROUP_TEMPLATE = "group_name";
    private final static String APP_TITLE_TEMPLATE = "{" + APP_NAME_TEMPLATE + "} / {" + APP_GROUP_TEMPLATE + "}";

    @Autowired Toolbar appToolBar;
    @Autowired AppCompatEditText appConfigContentEditText;
    @Autowired FloatingActionButton configAddButton;
    @Autowired DrawerLayout configDrawerLayout;
    @Autowired View configRecordAddBtn;
    @Autowired SpringView recordListSpringView;
    @Autowired RecyclerView recordListView;

    @Autowired(innerWired = true) @Inject AppConfigPresenter mPresenter;

    private AlertDialog configRecordAddDialog;
    private RecordListAdapter mAdapter;

    @Override
    protected int getLayoutId() {
        return R.layout.layout_app_config;
    }

    @Override
    protected void onCreate(View contentView, Bundle savedInstanceState) {
        DaggerAppConfigComponent.builder()
                .appComponent(CustomApplication.get(this).getAppComponent())
                .appConfigModule(new AppConfigModule(this))
                .build()
                .inject(this);
        // 使用路由框架初始化
        ARouter.getInstance().inject(this, mPresenter, contentView, savedInstanceState);
        // 设置toolbar
        statusBarHeight = 0;
        setToolBar(appToolBar);
        // 设置右上角按钮事件
        appToolBar.inflateMenu(R.menu.menu_app_config);
        // 初始化RecyclerView
        initRecyclerView();
        // 初始化视图
        bindViewListener();
        mPresenter.onStart();
    }

    private void initRecyclerView() {
        recordListView.setLayoutManager(new LinearLayoutManager(this));
        recordListView.setHasFixedSize(true);
        mAdapter = new RecordListAdapter();
        mAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN);
        mAdapter.isFirstOnly(true);
        mAdapter.bindToRecyclerView(recordListView);
        // 不允许刷新和不允许加载更多
        recordListSpringView.setGive(SpringView.Give.NONE);
        recordListSpringView.setType(SpringView.Type.FOLLOW);
        recordListSpringView.setHeader(new AcFunHeader(this, 0));
        recordListSpringView.setFooter(new AcFunFooter(this, 0));
    }

    private void bindViewListener() {
        Consumer<View> consumer = new Consumer<View>() {
            @Override
            public void accept(View view) {
                switch (view.getId()) {
                    case R.id.configAddButton : {
                        if (configDrawerLayout.isDrawerOpen(GravityCompat.END)) {
                            return;
                        }
                        configDrawerLayout.openDrawer(GravityCompat.END);
                        SystemUtil.hideSoftInput(appConfigContentEditText);
                        break;
                    }
                    case R.id.configRecordAddBtn : {
                        String configContent = appConfigContentEditText.getText().toString();
                        if (TextUtils.isEmpty(configContent)) {
                            SnackBarUtil.showSnackBar(AppConfigActivity.this, R.string.app_config_no_content_msg);
                            return;
                        }
                        if (null == configRecordAddDialog) {
                            createRecordAddDialog();
                        }
                        if (!configRecordAddDialog.isShowing()) {
                            configRecordAddDialog.show();
                        }
                        break;
                    }
                    case R.id.action_scan : {
                        // 跳转到二维码扫描界面
                        AppConfigActivityPermissionsDispatcher.directToCaptureActivityWithPermissionCheck(AppConfigActivity.this);
                        break;
                    }
                    default: {
                        break;
                    }
                }
            }
        };
        // 绑定展开侧边栏事件
        RxViewUtil.bindViewClickListener(configAddButton, bindToLifecycle(), consumer);
        // 绑定配置记录添加事件
        RxViewUtil.bindViewClickListener(configRecordAddBtn, bindToLifecycle(), consumer);
        // 绑定扫描按钮点击事件
        RxViewUtil.bindViewClickListener(appToolBar.findViewById(R.id.action_scan), bindToLifecycle(), consumer);
        // 记录项点击事件
        recordListView.addOnItemTouchListener(new OnItemClickListener() {
            @Override
            public void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position) {
                ConfigRecordBO configRecord = (ConfigRecordBO) mAdapter.getItem(position);
                if (null == configRecord) {
                    return;
                }
                final int recordPosition = position;
                final Long recordId = configRecord.getId();
                final String recordContent = configRecord.getContent();
                AlertDialog mDialog = new AlertDialog.Builder(AppConfigActivity.this, R.style.Theme_AppCompat_Light_Dialog_Alert)
                        .setTitle(configRecord.getTitle())
                        .setMessage(configRecord.getContent())       // FIXME 换成缩略图可能好点
                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                appConfigContentEditText.setText(recordContent);
                            }
                        })
                        .setNegativeButton(android.R.string.no, null)
                        .setNeutralButton(R.string.app_config_record_delete, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                deleteConfigRecord(recordId, recordPosition);
                            }
                        })
                        .create();
                mDialog.setOnShowListener(new DialogInterface.OnShowListener() {
                    @Override
                    public void onShow(DialogInterface dialog) {
                        ((AlertDialog)dialog).getButton(DialogInterface.BUTTON_NEUTRAL)
                                .setTextColor(SystemUtil.getColorByRes(AppConfigActivity.this.getResources(), android.R.color.holo_red_dark));
                    }
                });
                mDialog.setCanceledOnTouchOutside(false);
                mDialog.show();
            }
        });
    }

    @Override
    public void refreshRecordListView() {
        mPresenter.listConfigRecord()
                .compose(this.<ConfigRecordBO>bindToLifecycle())
                .subscribe(new Observer<ConfigRecordBO>() {
                    List<ConfigRecordVO> configRecordList = new ArrayList<ConfigRecordVO>();

                    @Override
                    public void onSubscribe(Disposable d) {
                        configRecordList.clear();
                    }

                    @Override
                    public void onNext(ConfigRecordBO configRecordBO) {
                        configRecordList.add(configRecordBO);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Timber.e(e);
                    }

                    @Override
                    public void onComplete() {
                        mAdapter.setNewData(configRecordList);
                    }
                });
    }

    @Override
    public void showAppConfigInfo(String appName, @BundleKeyConsts.AppConfigGroup String configTitle, String content) {
        // 设置标题
        String groupName = "";
        if (APP_CONFIG_GROUP_SERVER.equals(configTitle)) {
            groupName = getString(R.string.app_setting_server_title);
        } else if (APP_CONFIG_GROUP_EXTRA.equals(configTitle)) {
            groupName = getString(R.string.app_setting_extra_title);
        }
        appToolBar.setTitle(Phrase.from(APP_TITLE_TEMPLATE)
                .put(APP_NAME_TEMPLATE, appName)
                .put(APP_GROUP_TEMPLATE, groupName).format());
        // 显示之前配置的内容
        refreshContent(content);
    }

    @Override
    public void refreshContent(String content) {
        appConfigContentEditText.setText(content);
    }

    private void createRecordAddDialog() {
        @SuppressLint("InflateParams")
        View dialogView = getLayoutInflater().inflate(R.layout.dialog_configtitle, null,false);
        ((EditText)(dialogView.findViewById(R.id.appConfigTitleEditText))).addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {}

            @Override
            public void afterTextChanged(Editable s) {
                configRecordAddDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(s.length() != 0);
            }
        });
        configRecordAddDialog = new AlertDialog.Builder(AppConfigActivity.this, R.style.Theme_AppCompat_Light_Dialog_Alert)
                .setTitle(R.string.app_config_dialog_title)
                .setView(dialogView)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override public void onClick(DialogInterface dialog, int which) {
                        EditText editText = configRecordAddDialog.findViewById(R.id.appConfigTitleEditText);
                        if (null == editText) {
                            return;
                        }
                        // 隐藏输入法
                        SystemUtil.hideSoftInput(editText);
                        String configRecordTitle = editText.getText().toString();
                        if (TextUtils.isEmpty(configRecordTitle)) {
                            SnackBarUtil.showSnackBar(AppConfigActivity.this, R.string.app_config_record_title_hint);
                            return;
                        }
                        // 清空输入框
                        editText.setText("");
                        saveConfigRecord(configRecordTitle, appConfigContentEditText.getText().toString());
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        EditText editText = configRecordAddDialog.findViewById(R.id.appConfigTitleEditText);
                        if (null == editText) {
                            return;
                        }
                        // 隐藏输入法
                        SystemUtil.hideSoftInput(editText);
                    }
                })
                .create();
        configRecordAddDialog.setCanceledOnTouchOutside(false);
        configRecordAddDialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                EditText editText = configRecordAddDialog.findViewById(R.id.appConfigTitleEditText);
                if (null == editText) {
                    return;
                }
                Editable editable = editText.getText();
                if (null == editable) {
                    return;
                }
                configRecordAddDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(editable.length() != 0);
            }
        });
    }

    @SuppressLint("CheckResult")
    private void saveConfigRecord(@NonNull String title, @NonNull String content) {
        mPresenter.saveConfigRecord(title, content)
                .compose(this.<ConfigRecordBO>bindToLifecycle())
                .subscribe(new Consumer<ConfigRecordBO>() {
                    @Override
                    public void accept(ConfigRecordBO configRecordBO) {
                        // 刷新配置列表]
                        mAdapter.addData(0, configRecordBO);
                    }
                });
    }

    @SuppressLint("CheckResult")
    private void deleteConfigRecord(Long recordId, final int positionInList) {
        mPresenter.deleteConfigRecord(recordId)
                .compose(this.<Boolean>bindToLifecycle())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) {
                        mAdapter.remove(positionInList);
                    }
                });
    }

    /*****************************权限方面******************************************/
    @NeedsPermission(Manifest.permission.CAMERA)
    public void directToCaptureActivity() {
        ARouter.getInstance()
                .build(ActivityRouterConsts.ROUTER_APP_CAPTURE)
                .withString(Intents.Scan.MODE, Intents.Scan.QR_CODE_MODE)
                .direction(this, AppConfigPresenter.REQUEST_CODE_CAPTURE);
    }

    @OnShowRationale(Manifest.permission.CAMERA)
    public void showRationaleForCamera(final PermissionRequest request) {
        new AlertDialog.Builder(AppConfigActivity.this, R.style.Theme_AppCompat_Light_Dialog_Alert)
                .setMessage(R.string.permission_camera_rationale)
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.proceed();
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.cancel();
                    }
                })
                .show();
    }

    @OnPermissionDenied(Manifest.permission.CAMERA)
    public void showDeniedForCamera() {
        SnackBarUtil.showSnackBar(this, R.string.permission_camera_denied);
    }

    @OnNeverAskAgain(Manifest.permission.CAMERA)
    public void showNeverAskForCamera() {
        SnackBarUtil.showSnackBar(this, R.string.permission_camera_neverAsk);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        AppConfigActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }
    /*****************************权限方面******************************************/

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && null != data) {
            mPresenter.onResult(requestCode, data.getStringExtra(Intents.Scan.RESULT));
        }
    }

    @Override
    public void finish() {
        // 返回配置数据
        Intent data = new Intent();
        data.putExtra(BUNDLE_KEY_APP_CONFIG_CONTENT, appConfigContentEditText.getText().toString());
        setResult(RESULT_OK, data);
        super.finish();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN
                && (configDrawerLayout.isDrawerOpen(GravityCompat.END))) {
            configDrawerLayout.closeDrawer(GravityCompat.END);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPresenter.onDestroy();
    }

}
